import axios from 'axios'
import qs from 'qs'
import ls from '@/utils/ls'

const _axios = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_URL,
  timeout: 20e3,
})

let loadCount = 0

// 请求接口队列
let reqQueue = []

// 请求拦截
_axios.interceptors.request.use(
  (cfg) => {
    cfg.headers.authorization = ls.token()
    
    const notLoad = cfg?.data?.notLoading ?? cfg?.params?.notLoading
    reqQueue.push({
      url: cfg.url,
      loading: !notLoad,
      errDialog: !(cfg?.data?.notErrDialog ?? cfg?.params?.notErrDialog),
    })
    
    if (!notLoad) {
      loadCount++
      vio.gLoading(1)
    }
    [cfg.data, cfg.params].forEach(v => {
      if (v) {
        Reflect.deleteProperty(v, 'notLoading')
        Reflect.deleteProperty(v, 'notErrDialog')
      }
    })
    return cfg
  },
  (err) => {
    reqQueue = []
    console.error( 'reqErr::', err.message )
  }
)

// 响应拦截
_axios.interceptors.response.use(
  async (res) => {
    let url = res.config.url
    if (queItem(url)?.loading) {
      loadCount--
      if (loadCount <= 0) {
        vio.gLoading(2)
      }
    }
    
    if (res.data.errcode === 'e10') {
      delQue(url)
      ls.loginTargetUrl(location.href, '1h')
      if (location.pathname !== '/login') {
        location.href = '/login'
      }
      return
    }
    
    if (res.data.errcode !== 'suc') {
      if (queItem(url).errDialog) {
        // el.showErr(`${res.data.errmsg} ${endPath(url)}`)
        console.error( res.data.errmsg )
      }
      delQue(url)
      throw new Error(res.data.errmsg)
    }
    
    // 删除队列项
    delQue(url)
    return res.data
  },
  (err) => {
    const url = err.config.url
    delQue(url)
    // el.showErr(`${err.message} ${endPath(url)}`)
    throw new Error(err.errmsg)
  }
)

// 获取倒数两个斜杠的url 如:/a/b/c 得到: /b/c
function endPath(url) {
  return url?.match(/\/([^/]+\/[^/]+|[^/]+)$/i)?.[0]
}

function queItem(url) {
  return reqQueue.find(v => v.url === url)
}

function queIdx(url) {
  return reqQueue.findIndex(v => v.url === url)
}

// 删除队列项
function delQue(url) {
  reqQueue.splice(queIdx(url), 1)
}

// 封装 get post 方法
const my_axios = {
  get(url, params, opt = {}) {
    return _axios.get(url, Object.assign({
      params
    }, opt))
  },
  
  post(url, data, opt = {}) {
    opt.headers = {
      'Content-Type': `application/${opt.isQs ? 'x-www-form-urlencoded' : 'json'}`,
      ...opt.headers,
    }
    return _axios(Object.assign({
      url,
      method: 'POST',
      data: opt.isQs ? qs.stringify(data) : data
    }, opt))
  },
}

export default my_axios
